package cn.stylefeng.guns.modular.yingbao.handler;
import cn.stylefeng.guns.modular.yingbao.entity.*;
import cn.stylefeng.guns.modular.yingbao.service.*;
import cn.stylefeng.guns.modular.yingbao.util.RandomNum;
import cn.stylefeng.guns.rabbitmq.producer.Sender;
import cn.stylefeng.guns.rabbitmq.vo.MessageVo;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author jj
 * @date 2019/12/11 17:24
 */
@Service
@Slf4j
public class SysSellHandler {

    @Autowired
    SysSellLogService sysSellLogService;

    @Autowired
    SysUserService sysUserService;

    @Autowired
    UserMoneyService userMoneyService;

    @Lazy
    @Autowired
    private SysSellService sysSellService;

    @Autowired
    private SysSellSettingService sysSellSettingService;

    @Autowired
    SysRebateService sysRebateService;

    @Autowired
    SysRebateSettingService sysRebateSettingService;

    @Autowired
    Sender sender;

    @Async
    @Transactional(rollbackFor = Exception.class,timeout = 360)
    public void sellLogAdd(List<SysSell> list){
        List<SysSellLog> sysSellLogList = new ArrayList<>();
        for (SysSell sysSell:list){
            SysSellLog sysSellLog=new SysSellLog();
            sysSellLog.setCreateTime(new Date());
            sysSellLog.setOrdinal(sysSell.getOrdinal());
            sysSellLog.setPayType(sysSell.getPayType());
            sysSellLog.setPrice(sysSell.getPrice());
            sysSellLog.setStandby1(sysSell.getStandby1());
            sysSellLog.setStandby2(sysSell.getStandby3());
            sysSellLog.setUserid(sysSell.getBuyerUserid());
            if (sysSell.getStuats()=="2"){
                sysSellLog.setStandby3("审批完成！");
            }else if (sysSell.getStuats()=="0"){
                sysSellLog.setStandby3("审批已被拒绝！");
            }
            MessageVo msg = new MessageVo();
            msg.setMessage("您的挂售已审批");
            msg.setType("会员服务");
            msg.setId(sysSellLog.getUserid());
            msg.setCode(200);
            sender.sendBuy(msg);
            sysSellLogList.add(sysSellLog);
        }
        boolean b = sysSellLogService.saveBatch(sysSellLogList);
        if (b){
            log.info("------------------------挂售日志已处理成功！上传到队列------------");
        }else {
            log.info("------------------------挂售日志错误！！------------");
        }

    }

    @Async
    @Transactional(rollbackFor = Exception.class,timeout = 360)
    public void userMoneyHander(List<SysSell> list){
        for (SysSell sysSell:list){
            userMoney(sysSell);
        }
        log.info("------------------------完成所有金额修改！！------------");
    }

    @Async("asyncServiceExecutor")
    @Transactional(rollbackFor = Exception.class,timeout = 360)
    public void userMoney(SysSell sysSell) {
        Integer payType = sysSell.getPayType();
        if (payType==null ||payType==3){
            return;
        }
        Long price = sysSell.getPrice();
        Long buyerUserid = sysSell.getBuyerUserid();
        UserMoney userMoney = userMoneyService.getOne(new QueryWrapper<UserMoney>().eq("userid", buyerUserid));

        if (payType==0){
            userMoney.setAvailMoney(userMoney.getAvailMoney()+price);
        }else if (payType==1){
            userMoney.setExpandMoney(userMoney.getExpandMoney()+price);
        }else if (payType==2){
            userMoney.setRebateMoney(userMoney.getRebateMoney()+price);
        }
        long version = userMoney.getVersion();
        userMoney.setVersion(version+1);
        boolean update = userMoneyService.update(userMoney, new QueryWrapper<UserMoney>().eq("id", userMoney.getId()).eq("version", version));
        if (update){
            UserMoneyLog userMoneyLog =new UserMoneyLog();
            userMoneyLog.setCreateTime(new Date());
            userMoneyLog.setMoney(price);
            userMoneyLog.setUserid(userMoney.getUserid());
            userMoneyLog.setPayType(payType);
            userMoneyLog.setRemark("（回退）订单编号："+sysSell.getOrdinal());
            boolean insert = userMoneyLog.insert();
            if (insert){
                log.info("------------------------添加回退记录成功------------");
            }
            log.info("------------------------成功修改金额------------");
        }else {
            log.info("------------------------修改金额错误！！------------");
        }

    }
    /**
     * 订单支付倒计时
     * @param sysSell
     */
    @Async
    public void payQueue(SysSell sysSell,Long time){
        time=time*1000;
        mrMsg(sysSell);
        MessageVo msg = new MessageVo();
        msg.setType("超时处理" );
        msg.setTimestamp(time.toString());
        msg.setMessage(sysSell.getId());
        sender.sendMsg(msg);
    }

    /**
     * 订单支付倒计时
     * @param id
     */
    @Async
    @Transactional(rollbackFor = Exception.class,timeout = 360)
    public void payErrorHandler(long id){
        SysSell sysSell = sysSellService.getById(id);
        if (sysSell==null){
            log.error("消息丢失！！");
            return;
        }
        if (!"3".equals(sysSell.getStuats())){
            log.error("订单已支付！");
            return;
        }
        SysSellSetting settings = sysSellSettingService.getOne(null);

        SysUser sysUser = sysUserService.getById(sysSell.getSellerUserid());

        if (sysUser == null ||settings == null){
            log.error("异常错误！");
            return;
        }
        //是否冻结
        Integer isFrozen = settings.getIsFrozen();
        //是否挂售
        Integer isSell = settings.getIsSell();
        //是否可以买入
        Integer isBuy = settings.getIsBuy();

        if (isFrozen==1){
            sysUser.setStatus("2");
        }
        if (isBuy==1){
            sysUser.setBackup2("1");
        }
        if (isSell==1){
            sysUser.setBackup3("1");
        }
        Long version = sysUser.getVersion();
        sysUser.setVersion(version+1);
        csMsg(sysSell);
        boolean update = sysUserService.update(sysUser, new QueryWrapper<SysUser>().eq("id", sysUser.getId()).eq("version", version));
        if (!update){
            log.error("用户更新异常错误！");
            throw new UnsupportedOperationException("用户更新异常错误");
        }
        sysSell.setStuats("2");
        sysSell.setSellerUserid(null);
        Integer sellVersion = sysSell.getVersion();
        boolean update1 = sysSellService.update(sysSell, new QueryWrapper<SysSell>().eq("id", sysSell.getId()).eq("version", sellVersion));
        if (!update1){
            log.error("订单更新异常错误！");
            throw new UnsupportedOperationException("用户更新异常错误");
        }

    }

    /**
     * @description :待确定队列
     * @param sysSell
     * @date : 2019/12/16 9:57
     * @author : jj
     */
    @Async
    public void affirmQueue(SysSell sysSell,Long time) {
        time= time*1000;
        if (sysSell==null){
            log.error("订单错误！" );
        }

        qrMsg(sysSell);
        MessageVo msg = new MessageVo();
        msg.setType("卖家未确定超时处理" );
        msg.setTimestamp(time.toString());
        msg.setMessage(sysSell.getId());
        sender.sendQrMsg(msg);

    }

    /**
     * 订单待确认倒计时结果处理
     * @param id
     */
    @Async
    @Transactional(rollbackFor = Exception.class,timeout = 360)
    public void affirmHandler(long id){
        SysSell sysSell = sysSellService.getById(id);
        if (sysSell==null){
            log.error("消息丢失！！");
            return;
        }
        if (!"4".equals(sysSell.getStuats())){
            log.error("订单已确认！");
            return;
        }
        affirmOrder(sysSell);
    }

    /**
    * @description :返利
    * @param sysSell 
    * @param money 
    * @param type
    * @date : 2019/12/16 15:49
    * @author : jj
    */

    private void setSysRebate(SysSell sysSell,long money,int type,long userid){
        SysRebate sysRebate=new SysRebate();
        sysRebate.setUserid(userid);
        sysRebate.setMoney(money);
        sysRebate.setOrdinal(sysSell.getOrdinal());
        sysRebate.setRebateType(type);
        sysRebate.setCreateTime(new Date());
        boolean save = sysRebateService.save(sysRebate);
        if (!save){
            log.error("分销插入错误");
            throw new UnsupportedOperationException("分销插入错误");

        }

    }


    /**
     * @description :超时消息
     * @param sysSell
     * @date : 2019/12/13 14:41
     * @author : jj
     */
    private void csMsg(SysSell sysSell){
        SysSellLog sysSellLog=new SysSellLog();
        sysSellLog.setCreateTime(new Date());
        sysSellLog.setOrdinal(sysSell.getOrdinal());
        sysSellLog.setPayType(sysSell.getPayType());
        sysSellLog.setPrice(sysSell.getPrice());
        sysSellLog.setStandby1(sysSell.getStandby1());
        sysSellLog.setStandby2(sysSell.getStandby3());
        sysSellLog.setUserid(sysSell.getBuyerUserid());
        sysSellLog.setStandby3("超时订单！");
        boolean save = sysSellLogService.save(sysSellLog);
        if (!save){
            throw new UnsupportedOperationException("日志插入错误");
        }
        MessageVo msg = new MessageVo();
        msg.setMessage("您的挂售因买入长时间未付款，已被重新上架！");
        msg.setType("会员服务");
        msg.setId(sysSell.getBuyerUserid());
        msg.setCode(200);
        sender.sendBuy(msg);
        msg.setMessage("您因长时间未付款，已被冻结相应功能！请联系客服进行解冻");
        msg.setId(sysSell.getSellerUserid());
        sender.sendSell(msg);
    }

    /**
    * @description :买入，买出消息
    * @param sysSell
    * @date : 2019/12/13 14:41
    * @author : jj
    */
    private void mrMsg(SysSell sysSell){
        SysSellLog sysSellLog=new SysSellLog();
        sysSellLog.setCreateTime(new Date());
        sysSellLog.setOrdinal(sysSell.getOrdinal());
        sysSellLog.setPayType(sysSell.getPayType());
        sysSellLog.setPrice(sysSell.getPrice());
        sysSellLog.setStandby1(sysSell.getStandby1());
        sysSellLog.setStandby2(sysSell.getStandby3());
        sysSellLog.setUserid(sysSell.getBuyerUserid());
        sysSellLog.setStandby3("买入成功！");
        boolean save = sysSellLogService.save(sysSellLog);
        if (!save){
            throw new UnsupportedOperationException("日志插入错误");
        }
        MessageVo msg = new MessageVo();
        msg.setMessage("您的挂售已被人买入");
        msg.setType("买入服务");
        msg.setId(sysSell.getBuyerUserid());
        msg.setCode(200);
        sender.sendBuy(msg);
        msg.setMessage("您已买入");
        msg.setId(sysSell.getSellerUserid());
        sender.sendSell(msg);
    }

    /**
     * @description :付款，已付款消息
     * @param sysSell
     * @date : 2019/12/13 14:41
     * @author : jj
     */
    private void qrMsg(SysSell sysSell){
        SysSellLog sysSellLog=new SysSellLog();
        sysSellLog.setCreateTime(new Date());
        sysSellLog.setOrdinal(sysSell.getOrdinal());
        sysSellLog.setPayType(sysSell.getPayType());
        sysSellLog.setPrice(sysSell.getPrice());
        sysSellLog.setStandby1(sysSell.getStandby1());
        sysSellLog.setStandby2(sysSell.getStandby3());
        sysSellLog.setUserid(sysSell.getBuyerUserid());
        sysSellLog.setStandby3("付款成功！");
        boolean save = sysSellLogService.save(sysSellLog);
        if (!save){
            throw new UnsupportedOperationException("日志插入错误");
        }
        MessageVo msg = new MessageVo();
        msg.setMessage("您的挂售买家已付款");
        msg.setType("付款服务");
        msg.setId(sysSell.getBuyerUserid());
        msg.setCode(200);
        sender.sendBuy(msg);
        msg.setMessage("您已付款");
        msg.setId(sysSell.getSellerUserid());
        sender.sendSell(msg);
    }
    /**
     * @description :待确认超时消息
     * @param sysSell
     * @date : 2019/12/13 14:41
     * @author : jj
     */
    @Async
    public void drqMsg(SysSell sysSell){
        SysSellLog sysSellLog=new SysSellLog();
        sysSellLog.setCreateTime(new Date());
        sysSellLog.setOrdinal(sysSell.getOrdinal());
        sysSellLog.setPayType(sysSell.getPayType());
        sysSellLog.setPrice(sysSell.getPrice());
        sysSellLog.setStandby1(sysSell.getStandby1());
        sysSellLog.setStandby2(sysSell.getStandby3());
        sysSellLog.setUserid(sysSell.getBuyerUserid());
        sysSellLog.setStandby3("确认订单！");
        boolean save = sysSellLogService.save(sysSellLog);
        if (!save){
            throw new UnsupportedOperationException("日志插入错误");
        }
        MessageVo msg = new MessageVo();
        msg.setMessage("您的挂售因长时间未确认，已自动确认！如有疑问请尽快申诉");
        msg.setType("订单服务");
        msg.setId(sysSell.getBuyerUserid());
        msg.setCode(200);
        sender.sendBuy(msg);
        msg.setMessage("您的订单已完成");
        msg.setId(sysSell.getSellerUserid());
        sender.sendSell(msg);
    }

    /**
    * @description :确认处理
    * @param sysSell 
    * @date : 2019/12/17 11:21
    * @author : jj
    */
    @Transactional(rollbackFor = Exception.class,timeout = 360)
    public ResponseData affirmOrder(SysSell sysSell){

        sysSell.setStuats("5");
        sysSell.setAffirmTime(new Date());
        int sellVersion = sysSell.getVersion();
        sysSell.setVersion(sellVersion+1);
        boolean update1 = sysSellService.update(sysSell, new QueryWrapper<SysSell>().eq("id", sysSell.getId()).eq("version", sellVersion));
        if (!update1){
            log.error("订单更新异常错误！");
            throw new UnsupportedOperationException("订单更新异常错误");
        }

        //建仓金额更新
        UserMoney userMoney = userMoneyService.getOne(new QueryWrapper<UserMoney>().eq("userid",sysSell.getSellerUserid()));
        SysUser sysUser = sysUserService.getById(sysSell.getSellerUserid());
        if (userMoney == null||sysUser == null){
            log.error("异常错误！");
            throw new UnsupportedOperationException("订单更新异常错误");
        }
        userMoney.setCabinMoney(userMoney.getCabinMoney()+sysSell.getPrice());
        long version = userMoney.getVersion();
        userMoney.setVersion(version+1);
        boolean update2 = userMoneyService.update(userMoney, new QueryWrapper<UserMoney>().eq("id", userMoney.getId()).eq("version", version));
        if (!update2){
            log.error("用户金额更新异常错误！");
            throw new UnsupportedOperationException("用户金额更新异常错误");
        }
        //分销管理
        if (sysUser.getIsNewbie()!=1) {
            log.error("已不是新手");
            return ResponseData.success(200,"完成,不是新手",null);
        }
        Long referrerId = sysUser.getReferrerId();
        if (referrerId == null) {
            log.error("没有上级");
            return ResponseData.success(200,"完成,没有上级",null);
        }
        SysUser user = sysUserService.getById(referrerId);
        if (user == null) {
            log.error("没有该用户");
            return ResponseData.success(200,"完成,没有上级用户",null);
        }

        //一级分销
        UserMoney userMoney1 = userMoneyService.getOne(new QueryWrapper<UserMoney>().eq("userid",user.getId()));

        SysRebateSetting sysRebateSetting = sysRebateSettingService.getOne(null);
        //直推返利金额=后台设置百分比*产品价格
        long money = sysRebateSetting.getDirect() * sysSell.getPrice() / 100 ;
        userMoney1.setRebateMoney(userMoney1.getRebateMoney() + money);
        long version2 = userMoney1.getVersion();
        userMoney1.setVersion(version2 + 1);
        boolean update4 = userMoneyService.update(userMoney1, new QueryWrapper<UserMoney>().eq("id", userMoney1.getId()).eq("version", version2));
        if (!update4){
            log.error("一级分销盈利错误");
            throw new UnsupportedOperationException("一级分销盈利错误");
        }
        log.info("一级分销盈利");
        setSysRebate(sysSell, money, 0, userMoney1.getUserid());

        //二级

        Long referrerId1 = user.getReferrerId();

        UserMoney userMoney2 =  userMoneyService.getOne(new QueryWrapper<UserMoney>().eq("userid",referrerId1));
        if (userMoney2==null){
            log.error("没有第二级");
            return ResponseData.success(200,"完成,没有上上级用户",null);
        }
        long money1 = sysRebateSetting.getBetweent()* sysSell.getPrice() / 100 ;
        //间推返利金额=后台设置百分比*产品价格
        userMoney2.setRebateMoney(userMoney2.getRebateMoney() + money1);
        long version3 = userMoney2.getVersion();
        userMoney2.setVersion(version3 + 1);
        boolean update3 = userMoneyService.update(userMoney2, new QueryWrapper<UserMoney>().eq("id", userMoney2.getId()).eq("version", version3));
        if (!update3){
            log.error("二级分销盈利错误");
            throw new UnsupportedOperationException("二级分销盈利错误");
        }
        log.info("二级分销盈利");
        setSysRebate(sysSell, money1, 1, userMoney2.getUserid());
        drqMsg(sysSell);
        return ResponseData.success(200,"成功",null);

    }


    @Async
    @Transactional(rollbackFor = Exception.class,timeout = 360)
    public ResponseData batchInsert(SysSell entity,ContractSetting one){
        if(Integer.parseInt(entity.getTitle()) > 0){
            List<SysSell> lists = new ArrayList<>();
            for(int x = 0; x < Integer.parseInt(entity.getTitle());x++){
                SysSell sysSell = new SysSell();
                sysSell.setOrdinal(RandomNum.getUUID_16());
                sysSell.setPrice(entity.getPrice()*100);
                sysSell.setContractType(one.getContractType());
                sysSell.setStuats("2");
                sysSell.setPayType(3);
                sysSell.setStandby2(entity.getStandby2());
                sysSell.setStandby1(entity.getStandby1());
                sysSell.setBuyerUserid(entity.getBuyerUserid());
                sysSell.setVersion(0);
                lists.add(sysSell);
            }
            boolean b = sysSellService.saveOrUpdateBatch(lists);
            if(b){
                return ResponseData.success(200,"批量挂售成功",null);
            }
            return ResponseData.error(500,"批量错误");
        }
        return ResponseData.error(500,"你不给我个数,怎么添加");

    }
    /**
     * @description :申诉消息
     * @param sysSell
     * @date : 2019/12/13 14:41
     * @author : jj
     */
    @Async
    @Transactional(rollbackFor = Exception.class,timeout = 360)
    public void ssMsg(SysSell sysSell){
        SysSellLog sysSellLog=new SysSellLog();
        sysSellLog.setCreateTime(new Date());
        sysSellLog.setOrdinal(sysSell.getOrdinal());
        sysSellLog.setPayType(sysSell.getPayType());
        sysSellLog.setPrice(sysSell.getPrice());
        sysSellLog.setStandby1(sysSell.getStandby1());
        sysSellLog.setStandby2(sysSell.getStandby3());
        sysSellLog.setUserid(sysSell.getBuyerUserid());
        sysSellLog.setStandby3("申诉订单！");
        boolean save = sysSellLogService.save(sysSellLog);
        if (!save){
            throw new UnsupportedOperationException("日志插入错误");
        }
        MessageVo msg = new MessageVo();
        msg.setMessage("您的挂售已申诉");
        msg.setType("订单服务");
        msg.setId(sysSell.getBuyerUserid());
        msg.setCode(200);
        sender.sendBuy(msg);
        msg.setMessage("您的订单已被申诉");
        msg.setId(sysSell.getSellerUserid());
        sender.sendSell(msg);
    }
}
